package com.gennlife.dataformat.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.gennlife.common.utils.StringUtils;
import com.gennlife.common.utils.bean.BeanUtils;
import com.gennlife.dataformat.domain.*;
import com.google.common.collect.Lists;
import com.smqj.icu.PatientInfo;
import com.smqj.icu.SqlLink;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

import java.io.*;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
@Slf4j
public class ICUService {

    private static final String FILE_SUFFIX = "aa";
    private static final String PATIENT_INTO = "病人转入";
    private static final String PATIENT_HOME = "病人入室";
    private static final String PATIENT_DIED = "病人死亡";

    private static int DATA_TYPE_VITAL_SIGNS = 1;

    private static int DATA_TYPE_CARE_MEASURE = 2;

    private static int DATA_TYPE_CARE_RECORD = 3;

    private static String DB_NAME = ResourceBundle.getBundle("icu").getString("db.name");

    private static String REMOVE_FIRST = ResourceBundle.getBundle("icu").getString("remove.first");

    private static String IMPORT_FILE = ResourceBundle.getBundle("icu").getString("import.file");

    private static String MAX_THREAD_NUM = ResourceBundle.getBundle("icu").getString("max.thread.num");

    private static String ICU_RESULT_FOLDER = ResourceBundle.getBundle("icu").getString("icu.result.folder");

    private static Logger logger = LogManager.getLogger(com.smqj.icu.File2Gp.class.getName());

    private static Map<String, String> fileMin = new HashMap<>();

    private static List<IcuInfo> icuInfoList = new ArrayList<>();

    private static List<VitalSigns> vitalSignsList = new ArrayList<>();

    private static List<CareMeasure> careMeasureList = new ArrayList<>();

    private static List<CareRecord> careRecordList = new ArrayList<>();


    public void exec(final int threadNum, Map<Integer, HashSet<String>> filesMap, String dealFileType, String path) {
        ExecutorService excutor = Executors.newFixedThreadPool(threadNum); //使用线程池
        final CountDownLatch cdl = new CountDownLatch(threadNum);//使用计数器
        long st = System.currentTimeMillis();
        SqlLink sqlLink = new SqlLink();

        for (int k = 1; k <= threadNum; k++) {
            final int p = k;
            excutor.execute(new Thread(() -> {
                try {
                    HashSet<String> importFileNames = filesMap.get(p);
                    Iterator<String> it = importFileNames.iterator();
                    File importFile;
                    while (it.hasNext()) {
                        //遍历File[]数组
                        importFile = new File(path + "/" + it.next());
                        String fileSuffix = importFile.getName().substring(importFile.getName().lastIndexOf(".") + 1).toLowerCase(Locale.ROOT);
                        if (!importFile.isDirectory()) {
                            int type = 0;
                            if (fileSuffix.equals("aa") || fileSuffix.equals("xls")) {
                                type = DATA_TYPE_VITAL_SIGNS;
                            } else if (fileSuffix.equals("yed")) {
                                type = DATA_TYPE_CARE_MEASURE;
                            } else if (fileSuffix.equals("ded")) {
                                type = DATA_TYPE_CARE_RECORD;
                            }
                            if (dealFileType.indexOf(type + "") > -1) {
                                import2gp(path, importFile, type, p);
                            }
                        }
                    }
                    logger.info("线程" + p + "一共处理了" + importFileNames.size() + "个文件");
                    cdl.countDown();//计数器减一
                } catch (Exception e1) {
                    e1.printStackTrace();
                    logger.error("处理异常:" + e1.getMessage());
                }
            }

            ));
        }
        excutor.shutdown();//关闭线程池
        try {
            cdl.await();//线程等待
            long ut = System.currentTimeMillis() - st;
            logger.info(threadNum + "个线程一共耗费时间" + ut / 1000 + "s(" + ut + "ms)");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public Long dealFiles2Gp(String dealFileType, String path, int count) throws SQLException {
        Long importCount = 0L;
        File file = new File(path);
        String[] fs = file.list();    //遍历path下的文件和目录，放在File数组中
        long time1 = System.currentTimeMillis();

        //统计所有的信息
        String[] tempFs = new File(path + "_icu_importover").list();
        HashSet<String> patientIds = new HashSet<>();
        HashSet<String> visitIds = new HashSet<>();
        TreeSet<Integer> dates = new TreeSet<>();
        String[] tempStrs;
        Integer tempInt;
        for (String temp : fs) {
            tempStrs = temp.split("-");
            if (tempStrs.length == 4) {
                patientIds.add(tempStrs[0]);
                visitIds.add(tempStrs[0] + tempStrs[1]);
                try {
                    tempInt = Integer.parseInt(tempStrs[2]);
                    if (tempInt > 20000101) {
                        dates.add(tempInt);
                    }
                } catch (NumberFormatException e) {
                    logger.error("日期格式不正确");
                }
            }
        }
        dates.comparator();
        if (dates.size() > 0) {
            logger.info("1:本次处理" + dates.first() + "到" + dates.last() + "大约" + patientIds.size() + "个人的" + visitIds.size() + "次就诊记录");
        } else {
            logger.error("没有数据需要处理");
        }
        for (String temp : tempFs) {
            tempStrs = temp.split("-");
            if (tempStrs.length == 4) {
                patientIds.add(tempStrs[0]);
                visitIds.add(tempStrs[0] + tempStrs[1]);
                try {
                    tempInt = Integer.parseInt(tempStrs[2]);
                    if (tempInt > 20000101) {
                        dates.add(tempInt);
                    }
                } catch (NumberFormatException e) {
                    logger.error("日期格式不正确");
                }
            }
        }
        dates.comparator();
        tempFs = new File(path + "_icu_notimport").list();
        for (String temp : tempFs) {
            tempStrs = temp.split("-");
            if (tempStrs.length == 4) {
                patientIds.add(tempStrs[0]);
                visitIds.add(tempStrs[0] + tempStrs[1]);
                try {
                    tempInt = Integer.parseInt(tempStrs[2]);
                    if (tempInt > 20000101) {
                        dates.add(tempInt);
                    }
                } catch (NumberFormatException e) {
                    logger.error("日期格式不正确");
                }
            }
        }
        dates.comparator();
        if (dates.size() > 0) {
            logger.info("2:本程序累计一共处理了从" + dates.first() + "到" + dates.last() + "大约" + patientIds.size() + "个人的" + visitIds.size() + "次就诊记录");
        } else {
            logger.error("没有数据需要处理");
        }
        File importFile;
        Map<String, HashSet<String>> fileMap = dealFile(fs);
        HashSet<String> importFileNames = fileMap.get("importFileNames");
        HashSet<String> notImportFileNames = fileMap.get("notImportFileNames");
        logger.info("一共需要处理" + fs.length + "个文件,其中需要导入的文件有" + importFileNames.size() + "个。");
        //采取线程池处理
        Map<Integer, HashSet<String>> filesMap = null;
        int threadNum = 5;
        if (importFileNames.size() > 1000) {
            threadNum = Integer.parseInt(MAX_THREAD_NUM);
        }
        if (importFileNames.size() > 10) {
            filesMap = new HashMap<Integer, HashSet<String>>(threadNum);
            for (int j = 0; j < threadNum; j++) {
                filesMap.put(j + 1, new HashSet<>());
            }
            int fileCount = 0;
            Iterator<String> it = importFileNames.iterator();
            while (it.hasNext()) {
                for (int j = 0; j < threadNum; j++) {
                    if (fileCount % threadNum == j) {
                        filesMap.get(j + 1).add(it.next());
                    }
                }
                fileCount++;
            }
        } else if (importFileNames.size() > 0) {
            threadNum = 1;
            filesMap = new HashMap<Integer, HashSet<String>>(1);
            filesMap.put(1, importFileNames);
        }
        if (REMOVE_FIRST.equals("yes")) {
            for (String fName : notImportFileNames) {
                importFile = new File(path + "/" + fName);
                importFile.renameTo(new File(path + "_icu_notimport/" + importFile.getName()));
                logger.info("将不需要处理的的文件 " + fName + " 移动到指定目录");
            }
            logger.info("将不需要处理的 " + notImportFileNames.size() + " 个文件移动到指定目录");
        }
        if (IMPORT_FILE.equals("no")) {
            logger.info("只统计，不处理文件，退出");
            return 0L;
        }
        if (null != filesMap) {
            exec(threadNum, filesMap, dealFileType, path);
            save2Excel();
        }
        //先将不需要处理的文件移出去
        if (!REMOVE_FIRST.equals("yes")) {
            for (String fName : notImportFileNames) {
                importFile = new File(path + "/" + fName);
                importFile.renameTo(new File(path + "_icu_notimport/" + importFile.getName()));
                logger.info("将不需要处理的的文件 " + fName + " 移动到指定目录");
            }
            logger.info("将不需要处理的 " + notImportFileNames.size() + " 个文件移动到指定目录");
        }
        logger.info("第" + count + "次导出完成");
        File file1 = new File(path);
        if (file1.list().length > 0 && count < 11) {
            count++;
            logger.info("开始重新导入" + count);
            dealFiles2Gp(dealFileType, path, count);
        } else if (file1.list().length > 0 && count >= 10) {
            logger.error("循环导入仍有数据未导入");
        } else {
            logger.info("合计" + count + "次导入完成所有文件");
        }
        logger.info("本次导入一共耗时：" + ((System.currentTimeMillis() - time1) / 1000) + "秒");
        return importCount;
    }

    private void save2Excel() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");//设置日期格式
        String date = df.format(new Date());
        int count = 1;
        if (icuInfoList.size() > 1000000) {
            for (List<IcuInfo> icuInfos : Lists.partition(icuInfoList, 1000000)) {
                EasyExcel.write(ICU_RESULT_FOLDER + "/icuInfo_" + date + "-" + count + "(" + "进出icu时间" + ").xlsx", IcuInfo.class).sheet("Sheet1").doWrite(icuInfos);
                count++;
            }
        } else if (icuInfoList.size() > 0) {
            EasyExcel.write(ICU_RESULT_FOLDER + "/icuInfo_" + date + "-" + count + "(" + "icu进出时间" + ").xlsx", IcuInfo.class).sheet("Sheet1").doWrite(icuInfoList);
        }

        count = 1;
        if (vitalSignsList.size() > 1000000) {
            for (List<VitalSigns> vitalSigns : Lists.partition(vitalSignsList, 1000000)) {
                EasyExcel.write(ICU_RESULT_FOLDER + "/vitalSignsInfo_" + date + "-" + count + "(" + "就诊-生命体征" + ").xlsx", VitalSigns.class).sheet("Sheet1").doWrite(vitalSigns);
                count++;
            }
        } else if (vitalSignsList.size() > 0) {
            EasyExcel.write(ICU_RESULT_FOLDER + "/vitalSignsInfo_" + date + "-" + count + "(" + "就诊-生命体征" + ").xlsx", VitalSigns.class).sheet("Sheet1").doWrite(vitalSignsList);

        }
        count = 1;
        if (careMeasureList.size() > 1000000) {
            for (List<CareMeasure> careMeasures : Lists.partition(careMeasureList, 1000000)) {
                EasyExcel.write(ICU_RESULT_FOLDER + "/careMeasure_" + date + "-" + count + "(" + "就诊-特护系统" + ").xlsx", CareMeasure.class).sheet("Sheet1").doWrite(careMeasures);
                count++;
            }
        } else if (careMeasureList.size() > 0) {
            EasyExcel.write(ICU_RESULT_FOLDER + "/careMeasure_" + date + "-" + count + "(" + "就诊-特护系统" + ").xlsx", CareMeasure.class).sheet("Sheet1").doWrite(careMeasureList);

        }
        count = 1;
        if (careRecordList.size() > 1000000) {
            for (List<CareRecord> careRecords : Lists.partition(careRecordList, 1000000)) {
                EasyExcel.write(ICU_RESULT_FOLDER + "/careRecords_" + date + "-" + count + "(" + "就诊-特护记录" + ").xlsx", CareRecord.class).sheet("Sheet1").doWrite(careRecords);
                count++;
            }
        } else if (careRecordList.size() > 0) {
            EasyExcel.write(ICU_RESULT_FOLDER + "/careRecords_" + date + "-" + count + "(" + "就诊-特护记录" + ").xlsx", CareRecord.class).sheet("Sheet1").doWrite(careRecordList);
        }
        icuInfoList.clear();
        vitalSignsList.clear();
        careMeasureList.clear();
        careRecordList.clear();
    }

    public void import2gp(String path, File file, int type, int threadNum) {
        Map<String, PatientInfo> insertMap = new HashMap<>();
        IcuInfo icuInfo = new IcuInfo();
        try {
            // 当逐行读写大于2G的文本文件时推荐使用以下代码
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            BufferedReader in = new BufferedReader(new InputStreamReader(bis, "GBK"), 10 * 1024 * 1024);// 10M缓存
            String line;
            int i = 0;
            while (in.ready()) {
                line = in.readLine().replaceAll("\\u0000", "");
                resolve(insertMap, line, file.getName(), type, icuInfo, i);
                i++;
            }
            in.close();
            Long start = System.currentTimeMillis();
            int count = save2List(icuInfo, insertMap, type);
            logger.info("线程" + threadNum + "从" + file + "导出" + count + "条数据,处理文件花费" + (System.currentTimeMillis() - start) + "毫秒");
            //将处理完成的文件移动到备份目录
            file.renameTo(new File(path + "_icu_importover/" + file.getName()));
        } catch (Exception e) {
            logger.error("异常:" + e.getMessage());
            e.printStackTrace();
        }
    }

    private int save2List(IcuInfo icuInfo, Map<String, PatientInfo> insertMap, int type) {
        int j = 0;
        Collection<PatientInfo> values = insertMap.values();
        j = j + insertMap.values().size();
        //增加处理icu时间
        if (type == DATA_TYPE_VITAL_SIGNS) {
            values.forEach(t ->
                    {
                        VitalSigns vitalSigns = new VitalSigns();
                        vitalSigns.setPatientSn("1111");
                        BeanUtils.copyBeanProp(vitalSigns, t);
                        vitalSignsList.add(vitalSigns);
                    }
            );
            //如果有值就存
            if (icuInfo.getInIcuTime() != null) {
                icuInfoList.add(icuInfo);
                j++;
            }
        } else if (type == DATA_TYPE_CARE_MEASURE) {
            values.forEach(t ->
                    {
                        CareMeasure careMeasure = new CareMeasure();
                        careMeasure.setPatientSn(t.getPatientSn());
                        careMeasure.setVisitSn(t.getVisitSn());
                        careMeasure.setMeasureTime(t.getMeasureTime());
                        careMeasure.setGlasgow(t.getGlasgow());
                        careMeasure.setPupil(t.getPupil());
                        careMeasure.setOxygenInhalationMode(t.getOxygenInhalationMode());
                        careMeasure.setOxygenFlowRate(t.getOxygenFlowRate());
                        careMeasure.setInvasiveOrNo(t.getInvasiveOrNo());
                        careMeasure.setVentilationMode(t.getVentilationMode());
                        careMeasure.setRass(t.getRass());
                        careMeasure.setLungCompliance(t.getLungCompliance());
                        careMeasure.setIPAP(t.getIpap());
                        careMeasure.setEpap(t.getEpap());
                        careMeasure.setFTimes(t.getFTimes());
                        careMeasure.setPc(t.getPc());
                        careMeasure.setPs(t.getPs());
                        careMeasure.setPeep(t.getPeep());
                        careMeasure.setTidalVolume(t.getTidalVolume());
                        careMeasure.setFio2(t.getFio2());
                        careMeasure.setDataSource(t.getDataSource());
                        careMeasureList.add(careMeasure);
                    }
            );
        } else if (type == DATA_TYPE_CARE_RECORD) {
            values.forEach(t -> {
                        CareRecord careRecord = new CareRecord();
                        careRecord.setPatientSn(t.getPatientSn());
                        careRecord.setVisitSn(t.getVisitSn());
                        careRecord.setRecordTime(t.getRecordTime());
                        careRecord.setRecordSn(t.getRecordSn());
                        careRecord.setRecordInfo(t.getRecordInfo());
                        careRecord.setRecordDoc(t.getRecordDoc());
                        careRecord.setDataSource(t.getDataSource());
                        careRecordList.add(careRecord);
                    }
            );
        }
        return j;
    }


    /*   private String[] getSQL(int type) {
           String[] sqlList = new String[2];
           if (type == DATA_TYPE_VITAL_SIGNS) {
               sqlList[0] = "INSERT INTO " + DB_NAME + "visits_special_vital_signs (\"PATIENT_SN\", \"VISIT_SN\", \"MEASURE_TIME\", \"TEMPERATURE\", " +
                       "\"HEART_RATE\", \"SBP\", \"DBP\", \"MAP\", \"BREATHING\", \"SPO2\", \"CVP\", \"DATA_SOURCE\") " +
                       "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
               sqlList[1] = "DELETE FROM " + DB_NAME + "visits_special_vital_signs  WHERE \"PATIENT_SN\"=? AND \"VISIT_SN\"=? AND \"MEASURE_TIME\"=?;";
           } else if (type == DATA_TYPE_CARE_MEASURE) {
               sqlList[0] = "INSERT INTO " + DB_NAME + "visits_special_care_measure (\"PATIENT_SN\", \"VISIT_SN\", " +
                       "\"MEASURE_TIME\", \"GLASGOW\", \"PUPIL\", \"OXYGEN_INHALATION_MODE\", \"OXYGEN_FLOW_RATE\"," +
                       " \"INVASIVE_OR_NO\", \"VENTILATION_MODE\", \"RASS\", \"LUNG_COMPLIANCE\", \"IPAP\", \"EPAP\", " +
                       "\"F_TIMES\", \"PC\", \"PS\", \"PEEP\", \"TIDAL_VOLUME\", \"FIO2\", \"DATA_SOURCE\") " +
                       "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
               sqlList[1] = "DELETE FROM " + DB_NAME + "visits_special_care_measure WHERE \"PATIENT_SN\"=? AND \"VISIT_SN\"=? AND \"MEASURE_TIME\"=?;";
           } else if (type == DATA_TYPE_CARE_RECORD) {
               sqlList[0] = "INSERT INTO " + DB_NAME + "visits_special_care_record(\"PATIENT_SN\", \"VISIT_SN\", \"RECORD_TIME\"," +
                       " \"RECORD_SN\", \"RECORD_INFO\",\"RECORD_DOC\", \"DATA_SOURCE\") VALUES(?, ?, ?, ?, ?, ?, ?);";
               sqlList[1] = "DELETE FROM " + DB_NAME + "visits_special_care_record WHERE \"PATIENT_SN\"=? AND \"VISIT_SN\"=? AND \"RECORD_TIME\"=? AND \"RECORD_SN\"=?;";
           }
           return sqlList;
       }*/
    private String[] getSQL(int type) {
        String[] sqlList = new String[3];
        if (type == DATA_TYPE_VITAL_SIGNS) {
            sqlList[0] = "INSERT INTO   " + DB_NAME + "visits_special_vital_signs (PATIENT_SN, VISIT_SN, MEASURE_TIME, TEMPERATURE,"
                    + "HEART_RATE, SBP, DBP, MAP, BREATHING, SPO2, CVP, DATA_SOURCE)" +
                    "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

            sqlList[1] = "DELETE FROM   " + DB_NAME + "visits_special_vital_signs WHERE PATIENT_SN =?AND VISIT_SN =?" +
                    "AND MEASURE_TIME =?";

            sqlList[2] = "INSERT INTO   " + DB_NAME + "visits_special_icu_time (PATIENT_SN, VISIT_SN, IN_ICU_TIME, OUT_ICU_TIME,OUT_TYPE)" +
                    "VALUES(?, ?, ?, ?, ?)";
            ;
        } else if (type == DATA_TYPE_CARE_MEASURE) {
            sqlList[0] = "INSERT INTO   " + DB_NAME + "visits_special_care_measure(PATIENT_SN, VISIT_SN," +
                    "MEASURE_TIME, GLASGOW, PUPIL, OXYGEN_INHALATION_MODE, OXYGEN_FLOW_RATE" +
                    "INVASIVE_OR_NO, VENTILATION_MODE, RASS, LUNG_COMPLIANCE, IPAP, EPAP," +
                    "F_TIMES, PC, PS, PEEP, TIDAL_VOLUME, FIO2, DATA_SOURCE)" +
                    "VALUES( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            ;
            sqlList[1] = "DELETE FROM   " + DB_NAME + "visits_special_care_measure WHERE PATIENT_SN =?AND VISIT_SN =?" +
                    "AND MEASURE_TIME =?";
            ;
        } else if (type == DATA_TYPE_CARE_RECORD) {
            sqlList[0] = "INSERT INTO   " + DB_NAME + "visits_special_care_record(PATIENT_SN, VISIT_SN, RECORD_TIME," +
                    "RECORD_SN, RECORD_INFO, RECORD_DOC, DATA_SOURCE) VALUES( ?, ?, ?, ?, ?, ?, ?)";
            ;
            sqlList[1] = "DELETE FROM   " + DB_NAME + "visits_special_care_record WHERE PATIENT_SN =?AND VISIT_SN =?" +
                    "AND RECORD_TIME =?AND RECORD_SN =?";
            ;
        }
        return sqlList;
    }

    private void buildSql(PreparedStatement ptatm, IcuInfo info) throws SQLException {
        ptatm.setString(1, info.getPatientSn());
        ptatm.setString(2, info.getVisitSn());
        ptatm.setString(3, info.getInIcuTime());
        ptatm.setString(4, info.getOutIcuTime());
        ptatm.setString(5, info.getOutType());
        ptatm.addBatch();
    }

    private void buildSql(PreparedStatement ptatm, PreparedStatement delPtatm, PatientInfo info, int type) throws SQLException {
        if (type == DATA_TYPE_VITAL_SIGNS) {
            ptatm.setString(1, info.getPatientSn());
            ptatm.setString(2, info.getVisitSn());
            ptatm.setString(3, info.getMeasureTime());
            ptatm.setString(4, info.getTemperature());
            ptatm.setString(5, info.getHeartRate());
            ptatm.setString(6, info.getSbp());
            ptatm.setString(7, info.getDbp());
            ptatm.setString(8, info.getMap());
            ptatm.setString(9, info.getBreathing());
            ptatm.setString(10, info.getSpo2());
            ptatm.setString(11, info.getCvp());
            ptatm.setString(12, info.getDataSource());
            ptatm.addBatch();
//            delPtatm.setString(1, info.getPatientSn());
//            delPtatm.setString(2, info.getVisitSn());
//            delPtatm.setString(3, info.getMeasureTime());
//            delPtatm.addBatch();
        } else if (type == DATA_TYPE_CARE_MEASURE) {
            ptatm.setString(1, info.getPatientSn());
            ptatm.setString(2, info.getVisitSn());
            ptatm.setString(3, info.getMeasureTime());
            ptatm.setString(4, info.getGlasgow());
            ptatm.setString(5, info.getPupil());
            ptatm.setString(6, info.getOxygenInhalationMode());
            ptatm.setString(7, info.getOxygenFlowRate());
            ptatm.setString(8, info.getInvasiveOrNo());
            ptatm.setString(9, info.getVentilationMode());
            ptatm.setString(10, info.getRass());
            ptatm.setString(11, info.getLungCompliance());
            ptatm.setString(12, info.getIpap());
            ptatm.setString(13, info.getEpap());
            ptatm.setString(14, info.getFTimes());
            ptatm.setString(15, info.getPc());
            ptatm.setString(16, info.getPs());
            ptatm.setString(17, info.getPeep());
            ptatm.setString(18, info.getTidalVolume());
            ptatm.setString(19, info.getFio2());
            ptatm.setString(20, info.getDataSource());
            ptatm.addBatch();
        } else if (type == DATA_TYPE_CARE_RECORD) {
            ptatm.setString(1, info.getPatientSn());
            ptatm.setString(2, info.getVisitSn());
            ptatm.setString(3, info.getRecordTime());
            ptatm.setString(4, info.getRecordSn());
            ptatm.setString(5, info.getRecordInfo());
            ptatm.setString(6, info.getRecordDoc());
            ptatm.setString(7, info.getDataSource());
            ptatm.addBatch();
        }
    }

    private void resolve(Map<String, PatientInfo> insertMap, String line, String fileName, int type, IcuInfo icuInfo, int i) {
        PatientInfo info = new PatientInfo();
        String[] patientInfo = fileName.split("-");
        info.setPatientSn(patientInfo[0]);
        info.setVisitSn(patientInfo[1]);
        String fileSuffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(Locale.ROOT);
        try {
            if (type == DATA_TYPE_VITAL_SIGNS) {
                String[] params = line.split(" ");
                getIcuTime(fileName, fileSuffix, params, icuInfo, i);
                i++;
                if (params[1].equals("P**************")) {
                    info.setMeasureTime(params[2] + "-" + params[3].substring(0, 2) + "-" + params[3].substring(2) + " " + params[0]);
                    String temperature = Double.parseDouble(params[10]) > 0 ?
                            String.format("%.2f", Double.parseDouble(params[10]) / 10) : null;
                    info.setTemperature(temperature);
                    info.setHeartRate(Integer.parseInt(params[6]) > 0 ? Integer.parseInt(params[6]) + "" : null);
                    info.setSbp(Integer.parseInt(params[4]) > 0 ? Integer.parseInt(params[4]) + "" : null);
                    info.setDbp(Integer.parseInt(params[5]) > 0 ? Integer.parseInt(params[5]) + "" : null);
                    info.setMap(Double.parseDouble(params[4]) + 2 * Double.parseDouble(params[5]) > 0 ?
                            String.format("%.3f", (Double.parseDouble(params[4]) + 2 * Double.parseDouble(params[5])) / 3) : null);
                    info.setBreathing(Integer.parseInt(params[9]) > 0 ? Integer.parseInt(params[9]) + "" : null);
                    info.setSpo2(Integer.parseInt(params[7]) > 0 ? Integer.parseInt(params[7]) + "" : null);
                    info.setCvp(Integer.parseInt(params[17]) > 0 ? Integer.parseInt(params[17]) + "" : null);
                    info.setDataSource(fileName.substring(0, fileName.lastIndexOf(".")));

                    insertMap.put(info.getPatientSn() + info.getVisitSn() + info.getMeasureTime(), info);
                }
            } else if (type == DATA_TYPE_CARE_MEASURE) {
                line = line.replaceAll("\\$\\^\\^\\^\\^", "").replaceAll("\\^", "\\|");
                String[] params = line.split("\\|");
                if (params.length > 1) {
                    int key = Integer.parseInt(params[1]);
                    if (key < 17 && key != 8) {
                        String beforeDate = fileMin.get(patientInfo[0] + "-" + patientInfo[1]);
                        if (StringUtils.isEmpty(beforeDate)) {
                            beforeDate = patientInfo[2];
                        }
                        String measureTime = getYedData(type, Integer.parseInt(params[0]), beforeDate);
                        String mapKey = info.getPatientSn() + info.getVisitSn() + measureTime;
                        PatientInfo tempPatient = insertMap.get(mapKey);
                        if (tempPatient == null) {
                            tempPatient = new PatientInfo();
                            tempPatient.setPatientSn(patientInfo[0]);
                            tempPatient.setVisitSn(patientInfo[1]);
                            tempPatient.setMeasureTime(measureTime);
                        }
                        params[2] = params[2].replaceAll("\\$", "").trim();
                        if (params[2].length() > 0) {
                            if (key == 1) {
                                tempPatient.setGlasgow(params[2]);
                            } else if (key == 2) {
                                tempPatient.setPupil(params[2]);
                            } else if (key == 3) {
                                tempPatient.setOxygenInhalationMode(params[2]);
                            } else if (key == 4) {
                                tempPatient.setOxygenFlowRate(params[2]);
                            } else if (key == 5) {
                                tempPatient.setInvasiveOrNo(params[2]);
                            } else if (key == 6) {
                                tempPatient.setVentilationMode(params[2]);
                            } else if (key == 7) {
                                tempPatient.setRass(params[2]);
                            } else if (key == 9) {
                                tempPatient.setLungCompliance(params[2]);
                            } else if (key == 12) {
                                tempPatient.setFTimes(params[2]);
                            } else if (key == 13) {
                                tempPatient.setPc(params[2]);
                            } else if (key == 14) {
                                tempPatient.setPs(params[2]);
                            } else if (key == 15) {
                                tempPatient.setPeep(params[2]);
                            } else if (key == 16) {
                                tempPatient.setTidalVolume(params[2]);
                            }
                        }
                        PatientInfo temp = JSON.toJavaObject(JSON.parseObject(JSON.toJSONString(tempPatient)), PatientInfo.class);
                        temp.setPatientSn(null);
                        temp.setVisitSn(null);
                        temp.setMeasureTime(null);
                        tempPatient.setDataSource(fileName.substring(0, fileName.lastIndexOf(".")));
                        if (!JSON.toJSONString(temp).equals("{}")) {
                            insertMap.put(mapKey, tempPatient);
                        }
                    }
                }
            } else if (type == DATA_TYPE_CARE_RECORD) {
                line = line.replaceAll("\\^\\^\\^\\^\\^\\^", "").replaceAll("\\|\\$\\|\\$\\|\\$\\|\\$\\|\\$\\|\\$\\|\\$", "").replaceAll("\\|\\$\\|\\$\\|\\$\\|", "");
                String[] params = line.split("\\|");
                if (params.length > 3 && patientInfo.length > 2) {
                    String beforeDate = fileMin.get(patientInfo[0] + "-" + patientInfo[1]);
                    if (StringUtils.isEmpty(beforeDate)) {
                        beforeDate = patientInfo[2];
                    }
                    String time = getYedData(type, Integer.parseInt(params[0]), beforeDate);
                    info.setRecordTime(time + " " + params[2].replaceAll("\\$", "").trim());
                    info.setRecordSn(params[0] + "-" + params[1]);
                    info.setRecordInfo(params[3].replaceAll("\\$", ""));
                    info.setRecordDoc(params.length > 4 ? params[4] : "");
                    info.setDataSource(fileName.substring(0, fileName.lastIndexOf(".")));
                    insertMap.put(info.getPatientSn() + info.getVisitSn() + info.getRecordTime() + info.getRecordSn(), info);
                } else {
                    logger.error(fileName + "文件的行数据有问题，无法解析：" + line);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(fileName + "文件的行数据有问题，无法解析：" + line);
        }
    }

    /**
     * 获取icu入|出 时间
     *
     * @param fileSuffix
     * @param params
     * @param icuInfo
     * @param i
     */
    private void getIcuTime(String fileName, String fileSuffix, String[] params, IcuInfo icuInfo, int i) {
        String[] split = fileName.split("-");
        String patientSn = split[0];
        String visitSn = split[1];
        if (FILE_SUFFIX.equals(fileSuffix) && i == 0) {
            icuInfo.setPatientSn(patientSn);
            icuInfo.setVisitSn(visitSn);
            //入ICU的时间 默认保存第一条时间
            icuInfo.setInIcuTime(params[2] + "-" + params[3].substring(0, 2) + "-" + params[3].substring(2) + " " + params[0]);
        } else if (FILE_SUFFIX.equals(fileSuffix)) {
            if ((params[1]).indexOf(PATIENT_INTO) > -1 || params[1].indexOf(PATIENT_HOME) > -1) {
                icuInfo.setInIcuTime(params[2] + "-" + params[3].substring(0, 2) + "-" + params[3].substring(2) + " " + params[0]);
            }
            if (params[1].indexOf(PATIENT_DIED) > -1) {
                icuInfo.setOutIcuTime(params[2] + "-" + params[3].substring(0, 2) + "-" + params[3].substring(2) + " " + params[0]);
                icuInfo.setFlag(1);
                icuInfo.setOutType("2");
            } else if (icuInfo.getFlag() != 1) {
                //出ICU的时间 默认取最后一条作为出ICU的时间
                icuInfo.setOutIcuTime(params[2] + "-" + params[3].substring(0, 2) + "-" + params[3].substring(2) + " " + params[0]);
            }
        }
    }

    private String getYedData(int type, int sn, String beforeDate) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat nsf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date before = sf.parse(beforeDate);
            Calendar c = Calendar.getInstance();
            c.setTime(before);
            c.add(Calendar.DAY_OF_MONTH, ((sn + 1) / 2));
            if (type == DATA_TYPE_CARE_MEASURE) {
                return nsf.format(c.getTime()) + " " + (sn % 2 == 0 ? "06:00" : "18:00");
            } else {
                return nsf.format(c.getTime());
            }

        } catch (ParseException e) {
            logger.error("日期格式错误");
        }
        return "";
    }

    private Map<String, HashSet<String>> dealFile(String[] fileStrs) {
        String[] temp;
        String tempStr;
        Map<String, HashSet<String>> fileMap = new HashMap<>(2);
        Map<String, Integer> map = new HashMap<String, Integer>();
        Map<String, Integer> minMap = new HashMap<String, Integer>();
        logger.info("分析文件1。。。");
        for (String str : fileStrs) {
            String fileSuffix = str.substring(str.lastIndexOf(".") + 1).toLowerCase(Locale.ROOT);
            if (fileSuffix.equals("aa") || fileSuffix.equals("xls") || fileSuffix.equals("yed") || fileSuffix.equals("ded")) {
                str = str.replace("-AM", "02-").replace("-PM", "01-");
                temp = str.split("-");//病人ID-流水号-日期-AM/PM.yed ->病人ID-流水号-日期02/01-.yed
                if (temp.length > 3 && temp[2].length() == 10) {
                    tempStr = temp[0] + "-" + temp[1] + "-" + temp[3];
                    if (map.containsKey(tempStr)) {
                        try {
                            if (Integer.parseInt(temp[2]) > map.get(tempStr)) {
                                map.put(tempStr, Integer.parseInt(temp[2]));
                            }
                        } catch (NumberFormatException e) {
                            logger.error("日期格式不正确");
                        }
                    } else {
                        try {
                            map.put(tempStr, Integer.parseInt(temp[2]));
                        } catch (NumberFormatException e) {
                            logger.error("日期格式不正确");
                        }
                    }
                    if (minMap.containsKey(tempStr)) {
                        try {
                            if (Integer.parseInt(temp[2]) < minMap.get(tempStr)) {
                                minMap.put(tempStr, Integer.parseInt(temp[2]));
                            }
                        } catch (NumberFormatException e) {
                            logger.error("日期格式不正确");
                        }
                    } else {
                        try {
                            minMap.put(tempStr, Integer.parseInt(temp[2]));
                        } catch (NumberFormatException e) {
                            logger.error("日期格式不正确");
                        }
                    }
                }
            }

        }
        logger.info("分析文件2。。。");
        HashSet<String> importFileNames = new HashSet<>(map.size());
        String key;
        String fileValue;
        String tempValue;
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            key = entry.getKey();
            temp = key.split("-");
            fileValue = entry.getValue() + "";
            tempValue = fileValue.substring(fileValue.length() - 2).equals("02") ? "AM" : "PM";
            importFileNames.add(temp[0] + "-" + temp[1] + "-" + fileValue.substring(0, fileValue.length() - 2) + "-" + tempValue + temp[2]);
        }
        fileMin = new HashMap<>(minMap.size());
        for (Map.Entry<String, Integer> entry : minMap.entrySet()) {
            key = entry.getKey();
            temp = key.split("-");
            fileValue = entry.getValue() + "";
            fileMin.put(temp[0] + "-" + temp[1], fileValue.substring(0, fileValue.length() - 2));
        }
        logger.info("分析文件3。。。");
        HashSet<String> notImportFileNames = new HashSet<String>(fileStrs.length - importFileNames.size());
        for (int b = 0; b < fileStrs.length; b++) {
            tempStr = fileStrs[b];
            if (!importFileNames.contains(tempStr)) {
                notImportFileNames.add(tempStr);
            }
        }
        logger.info("分析文件4。。。");
        fileMap.put("importFileNames", importFileNames);
        fileMap.put("notImportFileNames", notImportFileNames);

        return fileMap;
    }


}

